//
//  NSObject+SHModel.m
//  SDemo
//
//  Created by gg on 2018/7/18.
//  Copyright © 2018年 gg. All rights reserved.
//

#import "NSObject+SHModel.h"
#import <objc/message.h>

@implementation NSObject (SHModel)

// 获取类里面所有方法
// class_copyMethodList(__unsafe_unretained Class cls, unsigned int *outCount)// 本质:创建谁的对象

// 获取类里面属性
//  class_copyPropertyList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)


///最简单的转化
+(instancetype)modelChangeDic:(NSDictionary *)dic{
    //创建对象
    id obj = [[self alloc] init];
    
    unsigned int count = 0;
    
    //获取对象列表
    /**
     class_copyIvarList: 获取类中的所有成员变量
     Ivar：成员变量
     第一个参数：表示获取哪个类中的成员变量
     第二个参数：表示这个类有多少成员变量，传入一个Int变量地址，会自动给这个变量赋值
     返回值Ivar *：指的是一个ivar数组，会把所有成员属性放在一个数组中，通过返回的数组就能全部获取到。
     count: 成员变量个数
     */

    Ivar *ivarArr = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++) {
        Ivar ivar = ivarArr[i];
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
//        NSLog(@"name = %@",name);
        //因为属性都是以_开头的，所以从第二个索引开始取值
        NSString *key = [name substringFromIndex:1];
        id value = dic[key];
        if (value) {
            [obj setValue:value forKey:key];
        }
    }
    
    return obj;
}


//model里面包含另一个model 嵌套model
+(instancetype)model2ChangeDic:(NSDictionary *)dic {
    id obj = [[self alloc] init];
    
    unsigned int count = 0;
    Ivar *ivarArr = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++) {
        Ivar ivar = ivarArr[i];
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        //获取成员变量类型
        NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        NSLog(@"ivarType : %@",ivarType);
        NSString *key = [name substringFromIndex:1];
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
        
        id value = dic[key];
        //二次转换 ：字典中的字典转模型 || 判断下value 是否是字典，并且是自定义对象才需要转化
        if ([value isKindOfClass:[NSDictionary class]] && ![ivarType hasPrefix:@"NS"]) {
            //根据字符串名称生成对象
            Class model = NSClassFromString(ivarType);
            if (model) {
                value = [model model2ChangeDic:value];
            }
        }
        
        if (value) {
            [obj setValue:value forKey:key];
        }
        
    }
    
    return  obj;
}

// 数组中装着模型 （模型中的属性是一个数组，数组中是字典模型）
+(instancetype)model3ChangeDic:(NSDictionary *)dic{
    id obj = [[self alloc] init];
    unsigned int count = 0 ;
    Ivar *ivarArr = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i ++ ) {
        Ivar ivar = ivarArr[i];
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        NSString *key = [name substringFromIndex:1];
        id value = dic[key];
        
        if ([value isKindOfClass:[NSArray class]]) {
            if ([self respondsToSelector:@selector(arrayContainModelClass)]) {
                // 转换成id类型，就能调用任何对象的方法
                id idSelf = self;
                NSString *type = [idSelf arrayContainModelClass][key];
                Class modelClass = NSClassFromString(type);
                NSMutableArray *arr = [NSMutableArray array];
                for (NSDictionary *ddd in value) {
                    //字典转model
                    id newv = [modelClass model3ChangeDic:ddd];
                    [arr addObject:newv];
                }
                
                //把模型赋值给value
                value = arr;
            }
        }
        
        if (value) {
            [obj setValue:value forKey:key];
        }
        
        
    }
    
    return obj;
}


@end
